/*
 * Copyright 2014 by État de Genève (Switzerland)
 * All rights reserved.
 *
 * Author: ELCA Informatique SA
 */
define(['plugins/router', 'i18n'], function(router, i18n) {

    var breadcrumb = {
        // whole list of crumbs
        crumbs: ko.observableArray(),
        // current list type we're in
        currentListType: '',

        // is it the far right crumb?
        isLast: isLast,

        // add a crumb to the list
        addCrumb: addCrumb,

        // when we change list, set the root of the crumb
        setRoot: setRoot,
        // search results usually happen after a setRoot
        setSearch: setSearch,
        // remove crumbs that have a 'type'
        removeDetailCrumbs: removeDetailCrumbs,

        addDetailCrumb: addDetailCrumb

    };

    // visible smart subset of the actual crumbs
    breadcrumb.visibleCrumbs = ko.computed(function() {

        if(this.crumbs().length > 5) {
            var subset = _.filter(this.crumbs(), function(c) {
                return c && c.type;
            });

            subset.push({ title: '...', navigate: null, link: null, type: null });

            Array.prototype.push.apply(subset, _.last(this.crumbs(), 3));

            return subset;
        }

        return this.crumbs();
    }, breadcrumb);

    return breadcrumb;

    /**
     * removes crumbs that are not specials.
     * e.g. form detail crumbs
     */
    function removeDetailCrumbs() {
        // remove all detail crumbs
        this.crumbs(_.filter(this.crumbs(), function(c) {
            return c && c.type;
        }));
    }

    /**
     * When the list type changes, crumbs are reset
     */
    function setRoot(listType) {

        listType = listType || this.currentListType;

        // if same type, do nothing
        this.crumbs([]);
        this.currentListType = listType;

        var typeI18n = !this.currentListType ? 'unknownlist' : this.currentListType.toLowerCase();

        this.addCrumb(i18n.t('cms:types.' + typeI18n), '#' + extractListType(), 'root');
    }

    /**
     * Extract the list type from the fragment of the router
     */
    function extractListType() {
        var link = (router.activeInstruction().fragment || '').match(/^([^/]+(\/[^/]+(\/[^/]+)?)?)/);

        return link ? link[0] : '';
    }

    /**
     * Extract the query string from the window URL
     */
    function extractParams() {
         var qs = window.location.href.match(/[^?]+(\?.*)$/);
        return qs ? qs[1] : '';
    }

    /**
     * search results are always after a root crumb
     */
    function setSearch(type) {
        this.setRoot(type);

        var url = '#' + extractListType() + extractParams();

        this.addCrumb(i18n.t('cms:breadcrumb.results'), url, 'search');
    }

    function addDetailCrumb(item, title, url) {

        this.crumbs.push({
            title: title,
            link: '#detail/' + item.type + '/' + item.id,
            navigate: function() {
                router.navigate(url);
            },
            type: null
        });
    }

    /**
     * Adds a crumb to the list:
     */
    function addCrumb(title, link, specialCrumbType) {
        title = title || '';

        link = link || '#' + router.activeInstruction().fragment;

        this.crumbs.push({ title: title, link: link, type: specialCrumbType, navigate: null });
    }

    function isLast(crumb) {
        return crumb === _.last(this.visibleCrumbs());
    }
});